/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.model;

import java.io.File;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBElement;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;

import net.bioteam.appweb.Config;
import net.bioteam.appweb.model.meta.Entries;
import net.bioteam.appweb.model.meta.Entry;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

public class ProgramMeta implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	public static final Log logger=LogFactory.getLog(ProgramMeta.class);
	Map<String, Entry> metaData=new HashMap<String, Entry>();
	
	long modTime;
	String name;
	
	
	public static final ProgramMeta GLOBAL_META=new ProgramMeta(".GLOBAL");
	
	public ProgramMeta(String name) 
	{
		this.name=name;
		//logger.info("the name is "+name);
		
		try {
			init();
		} catch (JAXBException e) {
			logger.error("error loading the program meta file ",e);
		}
	}
	
	public synchronized void init() throws JAXBException
	{
		File file=new File(Config.PROGRAM_META_DIR+File.separator+name+".xml");
		if (file.exists())
		{
			if ( modTime!=file.lastModified())
			{	
				metaData.clear();
				if (!name.equals(".GLOBAL"))
				{
				//	logger.info("all global meta to "+name);
					//inherit the global value.
					metaData.putAll(GLOBAL_META.getMetaData());
				}
				//local value will override  that from global.
				JAXBContext jc = JAXBContext.newInstance("net.bioteam.appweb.model.meta");
				Unmarshaller unmarshaller = jc.createUnmarshaller();
				Object obj = unmarshaller.unmarshal(file);
				JAXBElement<Entries> jcmd = (JAXBElement<Entries>) obj;
				Entries entries = (Entries) jcmd.getValue();
				for (Entry entry:entries.getEntry())
				{
					metaData.put(entry.getName(), entry);
				}
				modTime=file.lastModified();
				//logger.info("loaded meta for "+name);
			} else
			{
			//	logger.info("meta is not loaded since it is loaded before "+name);
				//TODO if global is updated, we need to update global.
				//for performance consideration. Ignore it.
				//expect user touch all program-specific meta after global file is touched.
			}
		} else
		{
			//logger.info(file.getAbsoluteFile()+" does not exists");
			metaData.clear();
			if (!name.equals(".GLOBAL"))
			{
				
				//inherit the global value.
				metaData.putAll(GLOBAL_META.getMetaData());
			//	logger.info("add global meta to 1 "+name);
			}
		}
		
	}

	public Map<String, Entry> getMetaData()  {
		return metaData;
	}
	
	

}
